<?php
class data_renren extends data_social {
	private $app_id;
	private $akey;
	private $skey;
	private $token_url;
	private $scope;
	private $config;
	public function __construct() {
		if (defined ( 'RENREN_APP_ID' ) and defined ( 'RENREN_AKEY' ) and defined ( 'RENREN_SKEY' ) and defined ( 'RENREN_TOKEN_URL' ) and defined ( 'RENREN_SCOPE' )) {
			$this->app_id		= RENREN_APP_ID;
			$this->akey			= RENREN_AKEY;
			$this->skey			= RENREN_SKEY;
			$this->token_url		= RENREN_TOKEN_URL;
			$this->scope		= RENREN_SCOPE;			// 参见http://wiki.dev.renren.com/wiki/%E6%9D%83%E9%99%90%E5%88%97%E8%A1%A8
			
			$this->config = new stdClass ();
			$this->config->APIURL			= 'http://api.renren.com/restserver.do'; // RenRen网的API调用地址，不需要修改
			$this->config->APPID			= $this->app_id;
			$this->config->APIKey			= $this->akey;
			$this->config->SecretKey		= $this->skey;
			$this->config->APIVersion		= '1.0'; // 当前API的版本号，不需要修改
			$this->config->decodeFormat	= 'json'; // 默认的返回格式，根据实际情况修改，支持：json,xml
			$this->config->redirecturi		= data_social::make_callback_url();
			$this->config->scope			= $this->scope;
			
			parent::__construct();
		}
	}
	/**
	 * 获取登陆的url
	 * @return String
	 */
	public function authorize_url($flag = 'iframe/setting') {
		if ($this->app_id) {
			$params = array (
				'client_id'		=> $this->app_id,
				'response_type'	=> 'code',
				'scope'		=> $this->scope,
				'redirect_uri'	=> data_social::make_callback_url(),				// 注意callback url一定要一致，否则没有返回结果
				'state'		=> data_social::make_state('renren', $flag),
//				'x_renew'		=> 'true'
			);
			$return = 'https://graph.renren.com/oauth/authorize?'.  http_build_query($params);
			return $return;
		} else return false;
	}
	public function code_2_token($code) {
		if ($this->akey and $code) {
			$oauthApi = new RenrenOAuthApiService ();
			$api_param = array (
					'client_id'		=> $this->akey,
					'client_secret'	=> $this->skey,
					'redirect_uri'	=> data_social::make_callback_url(),
					'grant_type'		=> 'authorization_code',
					'code'		=> $code 
			);
			 // (access_token, expires_in, refresh_token, scope, user=(id, name, avatar=(0=(type=avatar,url=http://...), 1=(type=tiny,url=http://...), 2=(type=main,url=http://...),3=(type=large,url=http://... ) ) ) )
			$api_result = $oauthApi->rr_post_curl ( $this->token_url, $api_param );  // 使用code换取token
			if ($api_result['access_token'] and $api_result['user']['id']) {
				// 重新整理token字段
				return array (
					'uid'			=> $api_result['user']['id'],
					'access_token'	=> $api_result['access_token'],
					'refresh_token'	=> $api_result['refresh_token'],
					'ctime'		=> time(),
					'expires_in'		=> $api_result['expires_in'],
					'name'		=> $api_result['user']['name'],
					'nick'			=> $api_result['user']['name']
				);
			} else {
				new data_error_devel('人人网code to token错误', array('code'=>$code, 'api_result'=>$api_result), __CLASS__, __FUNCTION__, __LINE__);
				return false;
			}
		} else return false;
	}

	public function token_valid_or_refresh_into_db ($token_from_db) {
		if (isset($token_from_db['access_token']) and isset($token_from_db['refresh_token'])) {
			// 检查token是否有效
			if ($this->is_token_valid($token_from_db['access_token'])) {			// 这里是用users.getInfo来判断是否有效，返回值中不包括与token相关的信息
				return $token_from_db;
			} else {								// 刷新token
				$oauthApi = new RenrenOAuthApiService ();
				$api_param = array (
					'client_id'		=> $this->akey,
					'client_secret'	=> $this->skey,
					'refresh_token'	=> $token_from_db['refresh_token'],
					'grant_type'		=> 'refresh_token' 
				);
				// 使用refresh_token换取新的token，当没有超时，返回的token与原token是一样的
				$api_result = $oauthApi->rr_post_curl ( $this->token_url, $api_param );		// (access_token, refresh_token, expires_in, scope)
				if ($api_result ['access_token'] and $api_result ['expires_in']>0) {
					$token_to_db = array (
						'uid'			=> $token_from_db['uid'],
						'access_token'	=> $api_result['access_token'],
						'refresh_token'	=> $api_result['refresh_token'],
						'ctime'		=> time(),
						'expires_in'		=> $api_result['expires_in'],
					);
					$this->save_token('renren', $token_to_db);		// 写入数据库
					return $token_to_db;
				} else {
					$token_to_db = array (
						'uid'			=> $token_from_db['uid'],
						'ctime'		=> time()
					);
					$this->save_token('renren', $token_to_db);		// 写入数据库
					new data_error_devel ( '人人refresh token失败', array ('token_from_db' => $token_from_db, 'api_result' => $api_result), __CLASS__, __FUNCTION__, __LINE__ );
					return false;
				}
			}
		} else return false;
	}
	private function is_token_valid ($access_token) {
//		return false;
		if ($this->get_user_info($access_token)) return true;
		else return false;
	}
	public function get_user_info ($access_token) {
		if ($access_token) {
			$client = new RenrenRestApiService ( $this->config );
			$api_param = array (
				'access_token' => $access_token
			);
			$api_result = $client->rr_post_curl ( 'users.getInfo', $api_param );
			if ($api_result[0]['uid'] and $api_result[0]['name']) {
				return array (
					'renren_id'	=> $api_result[0]['uid'],
					'name'	=> $api_result[0]['name'],
				);
			} else {
				new data_error_devel('人人网get user info错误', array('access_token'=>$access_token, 'api_result'=>$api_result), __CLASS__, __FUNCTION__, __LINE__);
				return false;
			}
		} else return false;
	}
	public function get_token ($uid) {
		$data_user = new data_user();
		$user = $data_user->one($uid);
		
		return $this->token_valid_or_refresh_into_db($user['renren_token']);
	}
	/**
	 * 
	 * @param int $uid
	 * @param bool $is_in_cache
	 * @return array = array (
	 *		array (renren_id, nickname=>'name')
	 *	)
	 */
	public function get_friends($uid, $token='') {
		$uid = intval($uid);
		
		if ($uid) {
			if ($token) {
				$client = new RenrenRestApiService ( $this->config );
				$limit = 500;
				$page = 1;
				$return = array ();
				while ( 1 ) {
					$api_param = array (
						'access_token' => $token['access_token'],
						'page' => $page,
						'count' => $limit,
						'fields' => '' 
					);
					$api_result = $client->rr_post_curl ( 'friends.getFriends', $api_param ); // array(id=>123456789,tinyurl=>http://...,sex=>1,name=>name,headurl=>http://...)
					if (is_array ( $api_result ) and sizeof ( $api_result ) > 0 and ! isset ( $api_result ['error_code'] )) {
						$return = array_merge ( $return, $api_result );
						$page = $page + 1;
						if (count ( $api_result ) < $limit) break; // 记录读完，跳出
					} else {
						break;
					}
				}
				if (count ( $return ) > 0) {
					$return = $this->friends_to_simple ( $return );
					$this->cache_write ( $uid, 'renren', 'friends', $return );
					return $return;
				} else {
					new data_error_devel('从人人API读取好友时出错，或者这人一个好友也没有？', array('uid'=>$uid, 'token'=>$token, 'api_result'=>$api_result), __CLASS__, __FUNCTION__, __LINE__);
					return false;
				}
			} else {
				$cache = $this->cache_read ( $uid, 'renren', 'friends' );
				if ($cache) {
					return $cache;
				} else {
					return false;
				}
			}
		}
	}
	/**
	 * 简化friends数组
	 * 
	 * @param type $array
	 * @return array = array (
	 *		array (renren_id, nickname=>'name')
	 *	)
	 */
	private function friends_to_simple($array) {
		if (is_array ( $array )) {
			foreach ( $array as $k => $v ) {
				$array [$k] = array (
						'renren_id' => $v ['id'],
						'nickname' => $v ['name'] 
				);
			}
			return $array;
		} else	return false;
	}
	/**
	 * 发布人人share然后用share add comment的方式@给好友
	 * @param type $url
	 * @param type $at
	 * @param type $access_token
	 * @return boolean
	 */
	public function post($url, $at, $access_token) {
		if ($url and $at and $access_token) {
			$api_param = array (
				'access_token'	=> $access_token,
				'type'			=> 6,
				'ugc_id'		=> 0,
				'user_id'		=> 0,
				'url'			=> $url
			);
			$client = new RenrenRestApiService ( $this->config );
			$api_result = $client->rr_post_curl ( 'share.share', $api_param );		// id,long,分享的ID;user_id,int,发起本次分享的用户ID;title,string,分享的标题;url,string,分享的链接地址....
			if (isset($api_result['id']) and isset($api_result['user_id']) and !isset($api_result ['error_code'])) {
				// 发布comment
				$api_param = array (
					'access_token'	=> $access_token,
					'user_id'		=> $api_result['user_id'],
					'share_id'		=> $api_result['id'],
					'content'		=> $at
				);
				$api_result = $client->rr_post_curl ( 'share.addComment', $api_param );		// result	int	1: 表示成功. 0: 表示失败
				if (isset($api_result['result']) and $api_result['result'] == 1 and !isset($api_result['error_code'])) {
					return true;
				} else new data_error_devel ('人人用户ShareAddRecomment时返回Error', array('api_result'=>$api_result), __CLASS__, __FUNCTION__, __LINE__);
			} else new data_error_devel ('人人用户Share时返回Error', array('api_result'=>$api_result), __CLASS__, __FUNCTION__, __LINE__);
		}
		return false;
	}
	
	
	
	
	/**
	 * -- 显示在网站上的样式，如果有$image，则显示在name，caption，description三行的前面 -----------------------------------------------------------
	 * ------------------------------------------------------------------------------------------------------------------------------------------------------------
	 *	XXXXX	张乐言 $message ... [@好友名字(好友id)]			// 14px normal
	 *	X PIC X
	 *	XXXXX	<a href=$nameurl>$name</a>				// 12px bold
	 *			$caption								// 12px normal
	 *			$description							// 12px normal
	 * 
	 *			<grey>1分钟前</grey> <a href=$action_link>$action_name</a>
	 * ------------------------------------------------------------------------------------------------------------------------------------------------------------
	 * @param Int $uid 
	 * @param string $message		200个中文或者英文字，使用mb_strlen来判断，utf8编码，其他字符集未尝试
	 * @param string $title			30
	 * @param string $titleurl        	
	 * @param string $description	200
	 * @param string $access_token        	
	 * @return int post_id
	 */
	public function xxx_publishFeed($message, $title, $titleurl, $description, $access_token) {
		$api_param = array (
			'access_token'	=> $access_token,
			'message'		=> $message,
			'name'		=> $title,
			'url'			=> $titleurl,
			'description'	=> ($description) ? $description : '　',		// 这里用中文全角空格
			'caption'		=> '',
			'image'		=> '',
			'action_name'	=> '来自：你我阅读圈',								// 10个字符
			'action_link'	=> 'http://uread.me' 
		);
		// 检查各参数字符长度
		if (	mb_strlen ( $api_param ['message'] )	< 201		and 
			mb_strlen ( $api_param ['name'] )		< 31		and 
			mb_strlen ( $api_param ['description'] )	< 201
		) {
			$client = new RenrenRestApiService ( $this->config );
			$api_result = $client->rr_post_curl ( 'feed.publishFeed', $api_param );			// {“post_id”:1233445 }
			if (! $api_result ['error_code']) {
				if ($api_result ['post_id']) {
					return $api_result ['post_id'];
				} else new data_error_devel ('人人用户发布消息时没有返回post_id', array('api_result'=>$api_result, 'api_param'=>$api_param), __CLASS__, __FUNCTION__, __LINE__);
			} else new data_error_devel ('人人用户发布消息时返回Error', array('api_result'=>$api_result), __CLASS__, __FUNCTION__, __LINE__);
		} else new data_error_devel ('人人用户发布消息时参数错误', array('uid'=>$uid), __CLASS__, __FUNCTION__, __LINE__);
		return false;
	}
}
?>